package Meter::Meterings;

#===============================================================================
#     REVISION:  $Id: Meterings.pm 40 2011-07-08 11:09:28Z xdr.box@gmail.com $
#  DESCRIPTION:  Class::DBI wrapper for 'meterings' table
#===============================================================================

use strict;
use warnings;

use base qw(Meter::DBI);

use Readonly;
Readonly our $VERSION => qw($Revision: 40 $) [1];

use English qw( -no_match_vars );

#use Smart::Comments;

use Meter::Utils qw(
    inflate_iso8601_date
    deflate_iso8601_date
);

sub init_table {
    my $class = shift;

    __PACKAGE__->set_up_table('meterings');

    __PACKAGE__->has_a( appartment_id => 'Meter::Appartments' );

    __PACKAGE__->has_a(
        start_date => 'DateTime',
        inflate    => \&inflate_iso8601_date,
        deflate    => \&deflate_iso8601_date,
    );
    __PACKAGE__->has_a(
        end_date => 'DateTime',
        inflate  => \&inflate_iso8601_date,
        deflate  => \&deflate_iso8601_date,
    );

    __PACKAGE__->add_constraint( 'start_amount >= 0',
        cold_water_start_amount => sub { shift >= 0 } );
    __PACKAGE__->add_constraint( 'end_amount >= start_amount',
        cold_water_end_amount => \&_check_end_amount_ge_start_amount );

    __PACKAGE__->add_constraint( 'start_amount >= 0',
        hot_water_start_amount => sub { shift >= 0 } );
    __PACKAGE__->add_constraint( 'end_amount >= start_amount',
        hot_water_end_amount => \&_check_end_amount_ge_start_amount );

    __PACKAGE__->add_constraint( 'end_date > start_date',
        end_date => \&_check_end_date_gt_start_date );

    return;
}

sub _check_end_amount_ge_start_amount {
    my ( $value, $self, $column_name, $changing ) = @_;

    my ($meter_type) = $column_name =~ /\A(cold|hot)/xms;
    ### meter_type: $meter_type

    my $start_amount = $meter_type . '_water_start_amount';
    my $end_amount   = $meter_type . '_water_end_amount';

    return $changing->{$end_amount} >= $changing->{$start_amount};
}

sub _check_end_date_gt_start_date {
    my ( $value, $self, $column_name, $changing ) = @_;

    my $start_date = _to_datetime( $changing->{'start_date'} );
    my $end_date   = _to_datetime( $changing->{'end_date'} );

    return $end_date > $start_date;
}

sub _to_datetime {
    my $value = shift;

    return ref $value eq 'DateTime'
        ? $value
        : inflate_iso8601_date($value);
}

1;
